from typing import Tuple, Union

import ujson
from peewee import IntegrityError

from cache.currency_cache import CurrencyCache
from common.g.g import G_LOGGER
from common.model.currency.currency import TotalCurrency
from common.utils.resp import RC
from common.v.v import CURRENCY, DATAORCODE
from schema.req_schema.currency_req_schema import AddNewCurrencyModel
from service.base import Service


class CurrencyService(Service):
    CACHE_CLS = CurrencyCache

    async def get_currency_list(self) -> Tuple[bool, Union[int, DATAORCODE]]:
        try:
            cache_data = await self.cache.get_currency_list(CURRENCY.TOTAL_CURRENCY_INFO)
            if cache_data:
                return True, DATAORCODE(data=ujson.loads(cache_data))
        except Exception as e:
            G_LOGGER.exception(f"从缓存获取数据失败:{e},尝试从DB获取数据")

        try:
            res = await TotalCurrency.search_instances(self.mgw, condition={}, fields=["id", "code", "name", "symbol"])
        except Exception as e:
            G_LOGGER.exception(f"查询币种信息异常:{e}")
            return False, DATAORCODE(data=None, code=RC.DB_ERROR, msg="服务异常,请稍后再试")
        try:
            if res:
                await self.cache.set_total_currency_info_list(CURRENCY.TOTAL_CURRENCY_INFO, ujson.dumps(list(res)), ex=30 * 60)
                await self.cache.add_item_to_currency_set(CURRENCY.TOTAL_CURRENCY_SET, [l.get("code") for l in res])
            else:
                await self.cache.set_total_currency_info_list(CURRENCY.TOTAL_CURRENCY_INFO, ujson.dumps([]), ex=60)
        except Exception as e:
            G_LOGGER.exception(f"更新缓存失败:{e},不影响业务")
        return True, DATAORCODE(data=list(res))

    async def add_new_currency(self, currency_model: AddNewCurrencyModel) -> Tuple[bool, DATAORCODE]:
        try:
            currency_id = await TotalCurrency.add_new_instance(self.mgw, **currency_model.dict())
        except IntegrityError as e:
            G_LOGGER.exception(f"重复添加币种:{e}")
            return False, DATAORCODE(data=None, code=RC.CURRENCY_ALREADY_EXIST, msg="币种已经存在")
        except Exception as e:
            G_LOGGER.exception(f"添加币种异常:{e}")
            return False, DATAORCODE(data=None, code=RC.DB_ERROR, msg="服务异常,请稍后再试")
        try:
            await self.cache.delete_total_currency_info_list(CURRENCY.TOTAL_CURRENCY_INFO)
            await self.cache.sadd(CURRENCY.TOTAL_CURRENCY_SET, currency_model.code)
        except Exception as e:
            G_LOGGER.exception(f"更新缓存失败,不影响业务:{e}")
        return True, DATAORCODE(data={"currency_id": currency_id})

    async def is_currency_exist(self, currency_code):
        return await self.cache.is_currency_exist(CURRENCY.TOTAL_CURRENCY_SET, currency_code)
